package dm_tool
{
	import dm_tool.enums.CharacterSequence;
	import dm_tool.enums.CharacterStatus;
	
	import flash.utils.ByteArray;
	
	import mx.collections.ArrayCollection;
	import mx.core.Application;
	import mx.utils.ObjectUtil;
	
	/**
	 * Character class, used for PC and NPC
	 *  
	 * @author jrags
	 * 
	 * TODO: Create property accessors for this class... blah
	 */	
	[Bindable]
	public class Character
	{
		public var Id:String;
		public var Name:String;
		
		/** Stats **/
		public var Strength:int;
		public var Constitution:int;
		public var Dexterity:int;
		public var Intelligence:int;
		public var Wisdom:int;
		public var Charisma:int;
		public var Ac:int;
		public var Level:int;
		public var HealingSurges:int;
		public var FortitudeDefense:int;
		public var ReflexDefense:int;
		public var WillpowerDefense:int;
		public var Initiative:int;
		public var StrengthModifier:int;
		public var ConstitutionModifier:int;
		public var DexterityModifier:int;
		public var IntelligenceModifier:int;
		public var WisdomModifier:int;
		public var CharismaModifier:int;
		public var DeathSavesCount:int;
		public var DeathSavesUsed:int;
		
		/** Health **/
		public var HitPointsCurrent:int;
		public var HitPoints:int;
		public var HitPointsTemp:int;
		
		/** Skils **/
		public var Acrobatics:int;
		public var Arcana:int;
		public var Bluff:int;
		public var Diplomacy:int;
		public var Dungeoneering:int;
		public var Endurance:int;
		public var Heal:int;
		public var History:int;
		public var Insight:int;
		public var Intimidate:int;
		public var Nature:int;
		public var Perception:int;
		public var Religion:int;
		public var Stealth:int;
		public var Streetwise:int;
		public var Thievery:int;
		public var Athletics:int;
		public var PassivePerception:int;
		public var PassiveInsight:int;
		public var SavingThrows:int;
		public var Speed:int;
		public var Size:int;
		public var AttackRolls:int;
		
		/** Powers **/
		public var Powers:ArrayCollection = new ArrayCollection();
		
		/** DM Specific **/
		public var Status:String;
		public var Turn:int;
		public var Sequence:String;
		public var PreviousSequence:String;
		public var Roll:int;
		public var InitiativeTotal:int;
		public var Reserve:Boolean;
		public var HealingSurgesUsed:int;
		
		public var quantity:int;
		public var isPc:Boolean;
		public var didReady:Boolean;
		public var isMinion:Boolean;
		public var imported:Boolean;
		
		public function Character(character:Character=null)
		{
			if (character is Character)
			{
				this.Id = character.Id
				this.Name = character.Name;
				
				/** Stats **/
				this.Strength = character.Strength;
				this.Constitution = character.Constitution;
				this.Dexterity = character.Dexterity;
				this.Intelligence = character.Intelligence;
				this.Wisdom = character.Wisdom;
				this.Charisma = character.Charisma;
				this.Ac = character.Ac;
				this.Level = character.Level;
				this.HealingSurges = character.HealingSurges;
				this.FortitudeDefense = character.FortitudeDefense;
				this.ReflexDefense = character.ReflexDefense;
				this.WillpowerDefense = character.WillpowerDefense;
				this.Initiative = character.Initiative;
				this.StrengthModifier = character.StrengthModifier;
				this.ConstitutionModifier = character.ConstitutionModifier;
				this.DexterityModifier = character.DexterityModifier;
				this.IntelligenceModifier = character.IntelligenceModifier;
				this.WisdomModifier = character.WisdomModifier;
				this.CharismaModifier = character.CharismaModifier;
				this.DeathSavesCount = character.DeathSavesCount;
				this.DeathSavesUsed = character.DeathSavesUsed;
				
				/** Health **/
				this.HitPointsCurrent = character.HitPointsCurrent;
				this.HitPoints = character.HitPoints;
				this.HitPointsTemp = character.HitPointsTemp;
				
				/** Skils **/
				this.Acrobatics = character.Acrobatics;
				this.Arcana = character.Arcana;
				this.Bluff = character.Bluff;
				this.Diplomacy = character.Diplomacy;
				this.Dungeoneering = character.Dungeoneering;
				this.Endurance = character.Endurance;
				this.Heal = character.Heal;
				this.History = character.History;
				this.Insight = character.Insight;
				this.Intimidate = character.Intimidate;
				this.Nature = character.Nature;
				this.Perception = character.Perception;
				this.Religion = character.Religion;
				this.Stealth = character.Stealth;
				this.Streetwise = character.Streetwise;
				this.Thievery = character.Thievery;
				this.Athletics = character.Athletics;
				this.PassivePerception = character.PassivePerception;
				this.PassiveInsight = character.PassiveInsight;
				this.SavingThrows = character.SavingThrows;
				this.Speed = character.Speed;
				this.Size = character.Size;
				this.AttackRolls = character.AttackRolls;
				
				/** Powers **/
				this.Powers = character.Powers;
				
				/** DM Specific **/
				this.Status = character.Status;
				this.Turn = character.Turn;
				this.Sequence = character.Sequence;
				this.PreviousSequence = character.PreviousSequence;
				this.Roll = character.Roll;
				this.InitiativeTotal = character.InitiativeTotal;
				this.Reserve = character.Reserve;
				this.HealingSurgesUsed = character.HealingSurgesUsed;
				
				this.quantity = character.quantity;
				this.isPc = character.isPc;
				this.didReady = character.didReady;
				this.isMinion = character.isMinion;
				this.imported = character.imported;
			}
		}
		
		/**
		 * This constructor if passed in a XML object will attempt to load a character builder save file
		 *  
		 * @param D20Character
		 * 
		 */	
		public static function importCharacter(D20Character:XML):Character
		{
			Application.application.logDebug("importCharacter("+D20Character.CharacterSheet.Details.name+")");
			
			var character:Character = new Character();
			
			character.Name 					= D20Character.CharacterSheet.Details.name;
	
			character.Strength 				= D20Character.CharacterSheet.StatBlock.Stat.(@name  ==  "Strength").@value;
			character.Constitution 			= D20Character.CharacterSheet.StatBlock.Stat.(@name  ==  "Constitution").@value;
			character.Dexterity 			= D20Character.CharacterSheet.StatBlock.Stat.(@name  ==  "Dexterity").@value;
			character.Intelligence 			= D20Character.CharacterSheet.StatBlock.Stat.(@name  ==  "Intelligence").@value;
			character.Wisdom 				= D20Character.CharacterSheet.StatBlock.Stat.(@name  ==  "Wisdom").@value;
			character.Charisma 				= D20Character.CharacterSheet.StatBlock.Stat.(@name  ==  "Charisma").@value;
			character.StrengthModifier 		= D20Character.CharacterSheet.StatBlock.Stat.(@name  ==  "Strength modifier").@value;
			character.ConstitutionModifier 	= D20Character.CharacterSheet.StatBlock.Stat.(@name  ==  "Constitution modifier").@value;
			character.DexterityModifier 	= D20Character.CharacterSheet.StatBlock.Stat.(@name  ==  "Dexterity modifier").@value;
			character.IntelligenceModifier 	= D20Character.CharacterSheet.StatBlock.Stat.(@name  ==  "Intelligence modifier").@value;
			character.WisdomModifier 		= D20Character.CharacterSheet.StatBlock.Stat.(@name  ==  "Wisdom modifier").@value;
			character.CharismaModifier 		= D20Character.CharacterSheet.StatBlock.Stat.(@name  ==  "Charisma modifier").@value;
			character.Ac 					= D20Character.CharacterSheet.StatBlock.Stat.(@name  ==  "AC").@value;
			character.DeathSavesCount 		= D20Character.CharacterSheet.StatBlock.Stat.(@name  ==  "Death Saves Count").@value;
			character.Level 				= D20Character.CharacterSheet.StatBlock.Stat.(@name  ==  "Level").@value;
			character.HitPoints 			= D20Character.CharacterSheet.StatBlock.Stat.(@name  ==  "Hit Points").@value;
			character.HealingSurges 		= D20Character.CharacterSheet.StatBlock.Stat.(@name  ==  "Healing Surges").@value;
			character.FortitudeDefense 		= D20Character.CharacterSheet.StatBlock.Stat.(@name  ==  "Fortitude Defense").@value;
			character.ReflexDefense 		= D20Character.CharacterSheet.StatBlock.Stat.(@name  ==  "Reflex Defense").@value;
			character.WillpowerDefense 		= D20Character.CharacterSheet.StatBlock.Stat.(@name  ==  "Will Defense").@value;
			character.Initiative 			= D20Character.CharacterSheet.StatBlock.Stat.(@name  ==  "initiative").@value;
			
			character.Acrobatics 			= D20Character.CharacterSheet.StatBlock.Stat.(@name  ==  "Acrobatics").@value;
			character.Arcana 				= D20Character.CharacterSheet.StatBlock.Stat.(@name  ==  "Arcana").@value;
			character.Bluff 				= D20Character.CharacterSheet.StatBlock.Stat.(@name  ==  "Bluff").@value;
			character.Diplomacy 			= D20Character.CharacterSheet.StatBlock.Stat.(@name  ==  "Diplomacy").@value;
			character.Dungeoneering 		= D20Character.CharacterSheet.StatBlock.Stat.(@name  ==  "Dungeoneering").@value;
			character.Endurance 			= D20Character.CharacterSheet.StatBlock.Stat.(@name  ==  "Endurance").@value;
			character.Heal 					= D20Character.CharacterSheet.StatBlock.Stat.(@name  ==  "Heal").@value;
			character.History 				= D20Character.CharacterSheet.StatBlock.Stat.(@name  ==  "History").@value;
			character.Insight 				= D20Character.CharacterSheet.StatBlock.Stat.(@name  ==  "Insight").@value;
			character.Intimidate 			= D20Character.CharacterSheet.StatBlock.Stat.(@name  ==  "Intimidate").@value;
			character.Nature 				= D20Character.CharacterSheet.StatBlock.Stat.(@name  ==  "Nature").@value;
			character.Perception 			= D20Character.CharacterSheet.StatBlock.Stat.(@name  ==  "Perception").@value;
			character.Religion 				= D20Character.CharacterSheet.StatBlock.Stat.(@name  ==  "Religion").@value;
			character.Stealth 				= D20Character.CharacterSheet.StatBlock.Stat.(@name  ==  "Stealth").@value;
			character.Streetwise 			= D20Character.CharacterSheet.StatBlock.Stat.(@name  ==  "Streetwise").@value;
			character.Thievery 				= D20Character.CharacterSheet.StatBlock.Stat.(@name  ==  "Thievery").@value;
			character.Athletics 			= D20Character.CharacterSheet.StatBlock.Stat.(@name  ==  "Athletics").@value;
			character.PassivePerception 	= D20Character.CharacterSheet.StatBlock.Stat.(@name  ==  "passive Perception").@value;
			character.PassiveInsight 		= D20Character.CharacterSheet.StatBlock.Stat.(@name  ==  "Passive Insight").@value;
			character.SavingThrows 			= D20Character.CharacterSheet.StatBlock.Stat.(@name  ==  "Saving Throws").@value;
			character.Speed 				= D20Character.CharacterSheet.StatBlock.Stat.(@name  ==  "Speed").@value;
			character.Size 					= D20Character.CharacterSheet.StatBlock.Stat.(@name  ==  "Size").@value;
			character.AttackRolls 			= D20Character.CharacterSheet.StatBlock.Stat.(@name  ==  "Attack Rolls").@value;
			
			//Iterate over the powers and create them
			for each (var powerXml:XML in D20Character.CharacterSheet.PowerStats.Power)
			{
				var power:Power = new Power(powerXml);
				//If there are weapons, add them
				for each (var weaponXml:XML in powerXml.Weapon)
				{
					power.weapons.addItem(new PowerWeapon(weaponXml));
				}
				character.Powers.addItem(power);
			}
			
			/** Set our internal fields **/
			character.HitPointsCurrent 		= character.HitPoints;
			character.HitPointsTemp			= 0;
			character.DeathSavesUsed		= 0;
			character.HealingSurgesUsed		= 0;
			character.InitiativeTotal		= 0;
			character.Roll					= 0;
			character.Turn					= 0;
			character.Status				= CharacterStatus.Ok;
			character.Sequence				= CharacterSequence.Reserve;
			character.PreviousSequence		= character.Sequence;
			character.Reserve				= true;
			character.isPc					= true;
			character.isMinion				= false;

			Application.application.logDebug(ObjectUtil.toString(character));
			
			return character;
		}
		
		public function doClone(source:Object):*
		{
			var cloneWork:ByteArray = new ByteArray();
			cloneWork.writeObject(source);
			cloneWork.position = 0;
			return (cloneWork.readObject());
		}

	}
}